#include "myhead.h"

/*
	udp接收组播信息
*/

int main()
{
	int udpsock;
	int ret;
	char buf[100]={0};
	char ipbuf[16];
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	bindaddr.sin_port=htons(20000);
	
	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	int addrsize=sizeof(otheraddr);
	
	//创建udp套接字
	udpsock=socket(AF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp");
		return -1;
	}
	
	//取消端口绑定的限制
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("bind");
		return -1;
	}
	
	//加入到组播组里面(申请入群)
	struct ip_mreq mreq;  //存放组播地址的结构体变量
	bzero(&mreq, sizeof(mreq));
	mreq.imr_multiaddr.s_addr = inet_addr("225.10.10.10"); //D类地址,必须跟sendto一致
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);  // 必须用这个宏定义
	setsockopt(udpsock, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof mreq);  //设置加入到组播组里面
	
	while(1)
	{
		//接收组播信息
		ret=recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&addrsize);
		printf("发送组播信息给你的那个家伙ip是:%s   端口是:%hu\n",inet_ntop(PF_INET,&(otheraddr.sin_addr.s_addr),ipbuf,16),ntohs(otheraddr.sin_port));
		printf("recvfrom 返回值是:%d  接收的组播内容：%s\n",ret,buf);
	}
	
	//关闭
	close(udpsock);
	return 0;
}